const XLSX = require('xlsx');
const ExcelJS = require('exceljs');
const path = require('path');
const fs = require('fs');

// 通用Excel文件解析函数
async function parseExcelFile(filePath, headerRow, dataStartRow) {
  const ext = path.extname(filePath).toLowerCase();
  let data = [];
  
  try {
    console.log(`开始解析文件: ${filePath}`);
    
    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      throw new Error(`文件不存在: ${filePath}`);
    }
    
    // 检查文件是否可读
    try {
      fs.accessSync(filePath, fs.constants.R_OK);
    } catch (accessError) {
      throw new Error(`文件无法读取: ${filePath} - ${accessError.message}`);
    }
    
    if (ext === '.xlsx') {
      // 使用exceljs解析xlsx文件
      const workbook = new ExcelJS.Workbook();
      
      try {
        await workbook.xlsx.readFile(filePath);
      } catch (readError) {
        throw new Error(`读取Excel文件失败: ${readError.message}`);
      }
      
      // 检查工作表数量
      if (workbook.worksheets.length === 0) {
        throw new Error('工作簿中没有任何工作表');
      }
      
      console.log(`工作簿中包含 ${workbook.worksheets.length} 个工作表`);
      
      // 获取第一个工作表（尝试多种方式）
      let worksheet = workbook.getWorksheet(1); // 通过索引获取
      
      // 如果通过索引获取失败，尝试通过名称获取
      if (!worksheet && workbook.worksheets.length > 0) {
        worksheet = workbook.worksheets[0];
        console.log(`通过数组索引获取工作表: ${worksheet.name}`);
      }
      
      // 如果仍然无法获取工作表，列出所有可用工作表
      if (!worksheet) {
        const sheetNames = workbook.worksheets.map(sheet => sheet.name);
        throw new Error(`无法获取工作表。可用工作表: ${sheetNames.join(', ')}`);
      }
      
      console.log(`使用工作表: ${worksheet.name}`);
      console.log(`工作表行数: ${worksheet.rowCount}`);
      console.log(`工作表列数: ${worksheet.columnCount}`);
      
      // 检查行号是否有效
      if (headerRow > worksheet.rowCount) {
        console.warn(`表头行号 ${headerRow} 超出工作表范围 (1-${worksheet.rowCount})，使用第1行作为表头`);
        headerRow = 1;
      }
      
      // 获取表头
      const headers = [];
      const headerRowObj = worksheet.getRow(headerRow);
      
      if (!headerRowObj) {
        throw new Error(`无法获取第 ${headerRow} 行`);
      }
      
      console.log(`成功获取第 ${headerRow} 行`);
      
      // 处理表头单元格，保留换行符
      headerRowObj.eachCell((cell, colNumber) => {
        headers[colNumber] = extractTextFromCell(cell, true);
        console.log(`列 ${colNumber}: ${headers[colNumber]}`);
      });
      
      // 读取数据
      for (let rowNumber = dataStartRow; rowNumber <= worksheet.rowCount; rowNumber++) {
        const row = worksheet.getRow(rowNumber);
        if (row) {
          const rowData = {};
          for (let colNumber = 1; colNumber <= headers.length; colNumber++) {
            const cell = row.getCell(colNumber); // 不会跳过空单元格
            const header = headers[colNumber] || `列${colNumber}`;
            rowData[header] = extractTextFromCell(cell, true);
          }
          data.push(rowData);
        }
      }
      
      console.log(`成功读取 ${data.length} 行数据`);
    } else if (ext === '.xls') {
      // 使用xlsx解析xls文件
      let workbook;
      try {
        workbook = XLSX.readFile(filePath);
      } catch (readError) {
        throw new Error(`读取XLS文件失败: ${readError.message}`);
      }
      
      if (!workbook.SheetNames || workbook.SheetNames.length === 0) {
        throw new Error('工作簿中没有任何工作表');
      }
      
      const sheetName = workbook.SheetNames[0];
      const worksheet = workbook.Sheets[sheetName];
      
      if (!worksheet) {
        throw new Error(`无法获取工作表: ${sheetName}`);
      }
      
      console.log(`使用工作表: ${sheetName}`);
      
      // 转换为JSON
      const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
      
      console.log(`工作表行数: ${jsonData.length}`);
      
      // 检查行号是否有效
      if (jsonData.length < headerRow) {
        console.warn(`表头行号 ${headerRow} 超出工作表范围 (1-${jsonData.length})，使用第1行作为表头`);
        headerRow = 1;
      }
      
      // 获取表头
      const headers = (jsonData[headerRow - 1] || []).map(header => 
        typeof header === 'string' ? header : ''
      );
      
      console.log(`表头: ${headers.join(', ')}`);
      
      // 提取数据
      for (let i = dataStartRow - 1; i < jsonData.length; i++) {
        const rowData = {};
        for (let j = 0; j < headers.length; j++) {
          if (headers[j]) {
            rowData[headers[j]] = extractTextFromXLS(jsonData[i][j], false);
          }
        }
        data.push(rowData);
      }
      
      console.log(`成功读取 ${data.length} 行数据`);
    } else {
      throw new Error(`不支持的文件格式: ${ext}`);
    }
  } catch (error) {
    console.error(`解析Excel文件出错: ${filePath}`, error);
    throw error;
  }
  
  return data;
}

// 从ExcelJS单元格中提取文本
function extractTextFromCell(cell, preserveNewlines = false) {
  if (!cell) return '';
  
  // 如果单元格有富文本内容
  if (cell.value && cell.value.richText) {
    return extractTextFromRichText(cell.value.richText, preserveNewlines);
  }
  
  // 如果单元格值本身就是富文本对象
  if (cell.value && typeof cell.value === 'object' && cell.value.richText) {
    return extractTextFromRichText(cell.value.richText, preserveNewlines);
  }
  
  // 普通文本值
  let text = cell.value !== null && cell.value !== undefined ? 
    String(cell.value) : '';
  
  // 根据参数决定是否保留换行符
  if (!preserveNewlines) {
    text = text.replace(/[\r\n]+/g, ' ');
  }
  
  return text;
}

// 从XLS数据中提取文本
function extractTextFromXLS(value, preserveNewlines = false) {
  if (!value) return '';
  
  // 如果值是富文本对象
  if (typeof value === 'object' && value.richText) {
    return extractTextFromRichText(value.richText, preserveNewlines);
  }
  
  // 普通文本值
  let text = value !== null && value !== undefined ? 
    String(value) : '';
  
  // 根据参数决定是否保留换行符
  if (!preserveNewlines) {
    text = text.replace(/[\r\n]+/g, ' ');
  }
  
  return text;
}

// 从富文本对象中提取纯文本
function extractTextFromRichText(richText, preserveNewlines = false) {
  if (!richText || !Array.isArray(richText)) return '';
  
  // 拼接所有富文本段的文本内容
  let text = richText
    .map(segment => {
      if (segment && segment.text) {
        return segment.text;
      }
      return '';
    })
    .join('')
    .trim();
  
  // 根据参数决定是否保留换行符
  if (!preserveNewlines) {
    text = text.replace(/[\r\n]+/g, ' ');
  }
  
  return text;
}

module.exports = {
  parseExcelFile,
  extractTextFromCell,
  extractTextFromRichText
};